/*
 * parser.c
 *
 *  Created on: 2013-5-9
 *      Author: xkaying
 */

#include "../common/list.h"

#include "parser.h"
#include "lexer.h"
#include "../typedef/prority.h"

#include <assert.h>
#include <stdlib.h>
//定义一个全局包索引

#include "../typedef/project.h"

Project *project;

struct _parser
{
	Package *package;
};

Package *ParserGetPackage(ProjectParser *parser)
{
	return parser->package;
}

Token *ptoken;
ProjectParser *Parser(Lexer *lexer)
{
	assert(lexer);
	ProjectParser *parser;
	parser = (ProjectParser*) malloc(sizeof(parser));
	parser->package = PackageInit(0);

	ptoken = LexerGetToken(lexer);
	int state;
	state = 0;
	Package *package;
	package = 0;
	int prority;
	prority = Prority_Protected;
	while (ptoken) {
		switch (state)
		{
			case 0: {
				package = ParserPackage(lexer, parser);
				if (package) {
					state = 1;
					continue;
				}
				//package包不存在
				printf("编译错误\n");
				return 0;
			}
			case 1: {
				//进入包内容读取
				switch (ptoken->type)
				{
					case TokenType_BlockStart: {
						state = 2;
						ptoken = LexerGetToken(lexer);
						continue;
					}
					case TokenType_Comment: {
						ptoken = LexerGetToken(lexer);
						continue;
					}
					default: {
						printf("包命名结束后,需要在{}中描述包内容.\n");
						return 0;
					}
				}
				printf("parser状态机错误.状态%d.\n", state);
				return 0;
			}
			case 2: {
				//进入包内容读取
				switch (ptoken->type)
				{
					case TokenType_End:
					case TokenType_Comment: {
						ptoken = LexerGetToken(lexer);
						continue;
					}
					case TokenType_BlockEnd: {
						//包读取结束,返回开始.
						state = 10;
						ptoken = LexerGetToken(lexer);
						continue;
					}
						//import 语句
					case TokenKey_IMPORT: {
						if (ParserImport(lexer, package)) {
							continue;
						}
						printf("编译错误\n");
						return 0;

					}
						//enum结构
					case TokenKey_ENUM: {
						//默认是protected
						if (ParserEnum(lexer, package, prority)) {
							continue;
						}
						printf("编译错误\n");
						return 0;
					}
						//interface 结构
					case TokenKey_INTERFACE: {
						if (ParserInterface(lexer, package, prority)) {
							continue;
						}
						printf("编译错误\n");
						return 0;
					}
						//class 结构
					case TokenKey_CLASS: {
						if (ParserClass(lexer, package, prority)) {
							continue;
						}
						printf("编译错误\n");
						return 0;
					}
					case TokenKey_PRIVATE: {
						prority = Prority_Private;
						state = 3;
						ptoken = LexerGetToken(lexer);
						continue;
					}
					case TokenKey_PROTECTED: {
						prority = Prority_Protected;
						state = 3;
						ptoken = LexerGetToken(lexer);
						continue;
					}
					case TokenKey_PUBLIC: {
						prority = Prority_Public;
						state = 3;
						ptoken = LexerGetToken(lexer);
						continue;
					}
					default: {
						printf("包命名结束后,需要在{}中描述包内容.\n");
						return 0;
					}
				}

				printf("parser状态机错误.状态%d.\n", state);
				return 0;
			}
			case 3: {
				//进入包内容读取
				switch (ptoken->type)
				{
					case TokenType_End: {
						state = 2;
						prority = Prority_Protected;
						ptoken = LexerGetToken(lexer);
						continue;
					}
					case TokenType_Comment: {
						ptoken = LexerGetToken(lexer);
						continue;
					}
						//enum结构
					case TokenKey_ENUM: {
						//默认是protected
						if (ParserEnum(lexer, package, prority)) {
							state = 2;
							prority = Prority_Protected;
							continue;
						}
						printf("编译错误\n");
						return 0;
					}
						//interface 结构
					case TokenKey_INTERFACE: {
						if (ParserInterface(lexer, package, prority)) {
							state = 2;
							prority = Prority_Protected;
							continue;
						}
						printf("编译错误\n");
						return 0;
					}
						//class 结构
					case TokenKey_CLASS: {
						if (ParserClass(lexer, package, prority)) {
							state = 2;
							prority = Prority_Protected;
							continue;
						}
						printf("编译错误\n");
						return 0;
					}
					default: {
						printf("public关键字后面只能跟随enum interface class之一.\n");
						return 0;
					}
				}
				printf("parser状态机错误.状态%d.\n", state);
				return 0;
			}
			case 10: {
				switch (ptoken->type)
				{
					case TokenType_End: {
						ptoken = LexerGetToken(lexer);
						continue;
					}
					case TokenType_Comment: {
						ptoken = LexerGetToken(lexer);
						continue;
					}
					default: {
						printf("第%d行:警告 程序内容需要写到包中,否则无效.\n", ptoken->line);
						continue;
					}
				}
				printf("parser状态机错误.状态%d.\n", state);
				return 0;
			}
			default: {
				printf("parser状态机错误.状态(default):%d.\n", state);
				return 0;
			}
		}
		//表示解析借宿
		printf("parser状态机错误.状态%d.\n", state);
		return 0;
	}
	return parser;
}
